<template>
  <div>
    <h1>Unicode</h1>
    <!-- 格式化 -->
    <div
      class="p-5 mt-5 artboard artboard-demo flex items-start bg-primary-100"
    >
      <div class="inline-block">
        <label class="relative inline-flex items-baseline cursor-pointer">
          <input
            type="checkbox"
            v-model="isFormatter"
            @input="handleFormatter"
            class="sr-only peer"
          />
          <div
            class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"
          ></div>

          <span
            class="inline-block ms-5 text-lg font-bold text-gray-700 dark:text-gray-600"
          >
            {{ spanTxt }}
          </span>
        </label>
      </div>
    </div>
    <!-- 文本转unicode 输入框 -->
    <div class="mt-10">
      <label
        for="message"
        class="inline-block p-3 mb-2 text-md font-bold text-gray-900 dark:text-white"
      >
        {{ isFormatter ? "字符" : "unicode" }}
      </label>
      <!-- 字符转unicode时使用的进制 -->
      <label class="p-5 ml-24 h-24 cursor-pointer">
        <span class="label-text">十进制</span>
        <input
          type="checkbox"
          v-model="hex"
          @input="handHex"
          class="ms-2 me-2 -mb-2 toggle theme-controller"
          :disabled="isFormatter"
        />
        <span class="label-text">十六进制</span>
      </label>

      <textarea
        rows="8"
        class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
        placeholder="请输入..."
        v-model="content"
        @input="handleContent"
      ></textarea>
    </div>

    <div class="mt-7">
      <!-- 忽略回车 -->
      <div
        class="ms-1 p-6 w-40 h-14 inline-flex items-center ps-4 border border-gray-200 rounded dark:border-gray-700"
      >
        <input
          type="checkbox"
          v-model="ignoreEnter"
          @input="handleIgnoreEnter"
          name="bordered-checkbox"
          disabled
          class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
        />
        <label
          for="bordered-checkbox-1"
          class="w-full py-4 ms-2 font-medium text-gray-900 dark:text-gray-300"
        >
          忽略回车
        </label>
      </div>

      <!-- unicode首尾拼接 -->
      <div
        class="ms-10 p-1 inline-block ps-4 border border-gray-200 rounded dark:border-gray-700"
      >
        <span class="font-medium text-gray-700 dark:text-gray-300">
          unicode首位拼接：
        </span>
        <input
          type="text"
          class="w-32 input input-bordered"
          placeholder="开头"
          v-model="headValue"
          @input="handleHeadValue"
        />
        <kbd
          class="px-2 py-1.5 ml-5 mr-5 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500"
          >{{ isFormatter ? "unicode" : "字符" }}
        </kbd>
        <input
          type="text"
          class="w-32 input input-bordered"
          placeholder="结尾[\n换]"
          v-model="tailValue"
          @input="handleTailValue"
        />
      </div>
      <!-- 字符分割符 -->
      <input
        type="text"
        placeholder="字符分隔符, 默认换行"
        v-model="splitValue"
        @input="handleSplitValue"
        class="ml-5 input input-bordered w-full max-w-xs"
      />
    </div>

    <!-- 结果-->
    <div class="mt-7">
      <label
        for="message"
        class="block mb-2 p-3 text-md font-bold text-gray-900 dark:text-white"
      >
        结果：
      </label>
      <textarea
        v-model="result"
        rows="8"
        class="block p-2.5 mt-5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
        placeholder=" "
        readonly
      ></textarea>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
const isFormatter = ref(true);
const content = ref("");
// 最终结果
const result = ref("");
const spanTxt = ref("字符转unicode");
// 首位拼接
const headValue = ref("");
const tailValue = ref("");
// 是否忽略回车
const ignoreEnter = ref(true);
// unicode 转 字符时判断是否时十六进制
const hex = ref(false);
// 字符分割符
const splitValue = ref("\n");
const handleFormatter = () => {
  if (isFormatter.value) {
    spanTxt.value = "unicode转字符";
  } else {
    spanTxt.value = "字符转unicode";
  }
  content.value = "";
  result.value = "";
};

// 字符转unicode
const handleContent = () => {
  convert();
};

// 首尾拼接
const handleTailValue = () => {
  convert();
};
const handleHeadValue = () => {
  convert();
};

// 忽略回车
const handleIgnoreEnter = () => {
  // if (ignoreEnter.value) {
  //   result.value = result.value.replace(/\n/g, "");
  // }
};

//
const handleSplitValue = () => {
  convert();
};

/**
 * 字符转unicode
 * @param str 字符
 * @returns {string} unicode
 */
function convertToUnicode(str: string) {
  let unicode = "";
  let arrayStr = Array.from(str);
  for (let i = 0; i < arrayStr.length; i++) {
    const charCode = arrayStr[i].codePointAt(0);
    unicode +=
      headValue.value +
      charCode.toString(16).toUpperCase() +
      tailValue.value.replace(/\\n/g, "\n") +
      splitValue.value.replace(/\\n/g, "\n");
  }
  return unicode;
}

/**
 * unicode转字符
 * @param str unicode
 * @returns {string} 字符
 */
function convertToChar(str: string) {
  if (splitValue.value) {
    let reg = new RegExp(splitValue.value.replace(/\\n/g, "\n"), "g");
    str = str.replace(reg, "");
  }
  let codePoints: string[] = [];
  if (headValue.value && tailValue.value) {
    let reg = new RegExp(headValue.value + "(.*?)" + tailValue.value, "g");
    let codePointsTmp = str.match(reg);
    if (codePointsTmp) {
      for (let i = 0; i < codePointsTmp.length; i++) {
        codePoints[i] = codePointsTmp[i].substring(
          headValue.value.length,
          codePointsTmp[i].length - tailValue.value.length
        );
      }
    }
  } else if (headValue.value) {
    codePoints = str.split(headValue.value);
  } else if (tailValue.value) {
    codePoints = str.split(tailValue.value);
  } else {
    codePoints[0] = str;
  }
  let codePointNum: number[] = [];

  // 把内码放到十进制数组中
  for (let i = 0; i < codePoints.length; i++) {
    codePointNum[i] = hex
      ? parseInt(codePoints[i], 16)
      : parseInt(codePoints[i]);
  }

  return codePointNum
    .map((cp) => String.fromCodePoint(cp))
    .join(splitValue.value);
}

function convert() {
  // 忽略回车
  handleIgnoreEnter();
  try {
    if (isFormatter.value) {
      // 字符转unicode
      result.value = convertToUnicode(content.value);
    } else {
      // unicode转字符
      result.value = convertToChar(content.value);
    }
  } catch (e) {
    console.log("11");
  }
}
</script>

<style scoped></style>
